/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cx1.web.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.cx1.model.Place;
import org.cx1.model.Listing;
import org.cx1.model.Photo;
import org.cx1.model.utils.KPlaceTypeIDs;
import org.cx1.model.utils.KPlaceTypes;
import org.cx1.model.utils.SearchOption;
import org.cx1.model.utils.SearchResult;
import org.cx1.model.utils.ServiceResponse;
import org.cx1.model.utils.SystemProperties;
import org.cx1.service.api.IPlaceService;
import org.cx1.service.api.IListingService;
import org.cx1.service.api.IPhotoService;
import org.cx1.service.api.ISearchService;
import org.cx1.service.impl.DListingService;
import org.cx1.service.impl.DPhotoService;
import org.cx1.service.impl.DPlaceService;
import org.cx1.service.impl.DSearchService;
import org.cx1.service.impl.MPlaceService;
import org.cx1.service.impl.MListingService;
import org.cx1.service.impl.MPhotoService;
import org.cx1.service.utils.FourSQ;
import org.cx1.service.utils.FourSQTip;
import org.cx1.service.utils.ImageProcessor;
import org.cx1.web.controller.action.ListingAction;
import org.cx1.web.controller.action.PlaceAction;
import org.cx1.web.utils.SessionUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.view.RedirectView;

/**
 *
 * @author ECH
 */
public class PlaceController extends BaseController {

    //private IPlaceService placeService = new MPlaceService();
    //private IPhotoService photoService = new MPhotoService();
    //private IListingService listingService = new MListingService();
    
    private IPlaceService placeService = new DPlaceService();
    private IPhotoService photoService = new DPhotoService();
    private IListingService listingService = new DListingService();
    
    public PlaceController() {
    }

    protected ModelAndView handleRequestInternal( HttpServletRequest request,
                                                  HttpServletResponse response) throws Exception {
        ModelAndView mav = new ModelAndView();
        Map map = new HashMap();
        
        boolean loggedin = false;
        String userID = SessionUtils.getUserID(request.getSession());   
        
        if (!StringUtils.isEmpty(userID)) {
            loggedin = true;
            map.put("loggedin", loggedin);
        }
        
        Map<String, Object> parameterMap = new HashMap<String, Object>();
        if (ServletFileUpload.isMultipartContent(request)) {
            parameterMap = this.getMultipartFormParams(request);
        } 
        else {
            parameterMap = this.getFormParams(request);
        }

        Map<String, String> formfields = (Map<String, String>) parameterMap.get("formfields");
        int action = StringUtils.isEmpty(formfields.get("a")) ? 0 : Integer.parseInt(formfields.get("a"));
           
        switch (action) {
            case PlaceAction.READ_ALL: {
                readAll(mav, map, request);
                break;
            }
            case PlaceAction.READ: {
                read(mav, map, request);
                break;
            }
            case PlaceAction.CREATE: {
                if (loggedin) { 
                    create(mav, map, request); 
                }
                else { 
                    mav.setView(new RedirectView("home.htm"));
                    return mav;                    
                }
                break;
            }
            case PlaceAction.UPDATE: {
                if (loggedin) {
                    update(mav, map, request);             
                }
                else {
                    mav.setView(new RedirectView("home.htm"));
                    return mav;                    
                }
                break;
            }    
            case PlaceAction.DELETE: {
                if (loggedin) {
                    delete(mav, map, request);
                }
                else {
                    mav.setView(new RedirectView("home.htm"));
                    return mav;                    
                }
                break;
            }
           
            case PlaceAction.UPDATE_PHOTO: {
                if (loggedin) {
                    updatePhoto(mav, map, request, parameterMap);
                }
                else {
                    mav.setView(new RedirectView("home.htm"));
                    return mav;                    
                }
                break;
            }
            case PlaceAction.CREATE_PHOTO: {
                if (loggedin) {
                    createPhoto(mav, map, request, parameterMap);
                }
                else {
                    mav.setView(new RedirectView("home.htm"));
                    return mav;                    
                }
                break;
            }
            case PlaceAction.REMOVE_PHOTO: {
                if (loggedin) {
                    deletePhoto(mav, map, request, parameterMap);
                }
                else {
                    mav.setView(new RedirectView("home.htm"));
                    return mav;                    
                }
                break;
            }
            case PlaceAction.READ_ALL_MANAGE: {                      
                if (loggedin) {
                    readAll_manage(mav, map, request);          
                }
                else {
                    mav.setView(new RedirectView("home.htm"));
                    return mav;                    
                }
                break;
            }    
            default: {
                readAll(mav, map, request);
                break;
            }
        }

        map.put("host", SystemProperties.SYSTEM_HOST);
        map.put("port", SystemProperties.SYSTEM_PORT);
        map.put("props", this.getSystemProperties());
        
        mav.addObject("model", map);
        return mav;
    }

    private void readAll(ModelAndView mav, Map map, HttpServletRequest request) {
        String offset = request.getParameter("offset");
        String limit = request.getParameter("limit");
        ServiceResponse<List<Place>> response = placeService.readAll(StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        
        ServiceResponse<List<Place>> response1 = placeService.readAllByType(KPlaceTypes.CITY.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        ServiceResponse<List<Place>> response2 = placeService.readAllByType(KPlaceTypes.DISTRICT.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        ServiceResponse<List<Place>> response3 = placeService.readAllByType(KPlaceTypes.BUILDING.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        ServiceResponse<List<Place>> response4 = placeService.readAllByType(KPlaceTypes.VILLAGE.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
                
        map.put("places", response.getResponse());
        
        map.put("cities", response1.getResponse());
        map.put("districts", response2.getResponse());
        map.put("buildings", response3.getResponse());
        map.put("villages", response4.getResponse());
        mav.setViewName("placeall");
    }
    
    private void readAll_manage(ModelAndView mav, Map map, HttpServletRequest request) {
        String offset = request.getParameter("offset");
        String limit = request.getParameter("limit");
        ServiceResponse<List<Place>> response = placeService.readAll(StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        
        ServiceResponse<List<Place>> response1 = placeService.readAllByType(KPlaceTypes.CITY.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        ServiceResponse<List<Place>> response2 = placeService.readAllByType(KPlaceTypes.DISTRICT.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        ServiceResponse<List<Place>> response3 = placeService.readAllByType(KPlaceTypes.BUILDING.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
        ServiceResponse<List<Place>> response4 = placeService.readAllByType(KPlaceTypes.VILLAGE.getId(), StringUtils.isEmpty(offset) ? 0 : Integer.parseInt(offset), StringUtils.isEmpty(limit) ? 0 : Integer.parseInt(limit));
                
        map.put("places", response.getResponse());
        
        map.put("cities", response1.getResponse());
        map.put("districts", response2.getResponse());
        map.put("buildings", response3.getResponse());
        map.put("villages", response4.getResponse());
        mav.setViewName("placeall_manage");
    }
    
    private ISearchService searchService = new DSearchService();
    
    private void read(ModelAndView mav, Map map, HttpServletRequest request) {
        String id = request.getParameter("id");
        
        ServiceResponse<Place> response = placeService.read(id);
        //ServiceResponse<List<Listing>> response1 = listingService.readPlaceListings(id, 0, 0);
        
        List<Place> places = new ArrayList<Place>();        
        Place place1 = new Place();        
        place1.setId(id);        
        places.add(place1);
        
        SearchOption searchOption = new SearchOption();
        searchOption.setPlaces(places);
        searchOption.setPage(1);
        searchOption.setItemsPerPage(12);
        
        
        searchOption.setLeaseTerm(1);
        ServiceResponse<SearchResult> response1 = this.searchService.searchListings3(searchOption); 
                
        searchOption.setLeaseTerm(2);
        ServiceResponse<SearchResult> response2 = this.searchService.searchListings3(searchOption);
            
        //ServiceResponse<List<Listing>> response1 = listingService.readPlaceListings(id, 0, 0, 1);
        //ServiceResponse<List<Listing>> response2 = listingService.readPlaceListings(id, 0, 0, 2);
        
        Place place = response.getResponse();
        List<FourSQTip> foursqTips = null;
        if (place != null && !StringUtils.isEmpty(place.getFoursqVenueID())) {
            FourSQ fsq = new FourSQ();
            foursqTips = fsq.readVenueTips(place.getFoursqVenueID());
        }
        if (place != null) {
            placeService.incrementViews(id);
        }
            
        
        map.put("place", response.getResponse());
        map.put("longTermListings", response1.getResponse().getListings());
        map.put("shortTermListings", response2.getResponse().getListings());
        map.put("foursqTips", foursqTips);
        
        if (isThisRequestCommingFromAMobileDevice(request)) {
            mav.setViewName("place_mobile");
        }
        else {            
            mav.setViewName("place");
        }
    }
    
    private void create(ModelAndView mav, Map map, HttpServletRequest request) {
        if (!StringUtils.isEmpty(request.getParameter("s"))) {           
            String placeTypeID = request.getParameter("placeTypeID");
            
            String title = request.getParameter("title");
            String description = request.getParameter("description");
            String shortDescription = request.getParameter("shortDescription");
            String notes = request.getParameter("notes");
            
            String address = request.getParameter("address");
            
            String number = request.getParameter("number");
            String street = request.getParameter("street");
            String barangay = request.getParameter("barangay");
            String zip = request.getParameter("zip");
            String country = request.getParameter("country");
            String region = request.getParameter("region");
            String city = request.getParameter("city");
                        
            String lat = request.getParameter("lat");
            String lng = request.getParameter("lng");
            
            String wikiURL = request.getParameter("wikiURL");
            String foursqVenueID = request.getParameter("foursqVenueID");
            
            String primaryPhotoID = request.getParameter("primaryPhotoID");
            String photoIDs = request.getParameter("photoIDs");
        
            String cityIDs = request.getParameter("cityIDs");
            String districtIDs = request.getParameter("districtIDs");
            String buildingIDs = request.getParameter("buildingIDs");
            String villageIDs = request.getParameter("villageIDs");
            
            Place place = new Place();          
            place.setPlaceTypeID(placeTypeID);
            
            place.setTitle(title);
            place.setDescription(description);
            place.setShortDescription(shortDescription);
            place.setNotes(notes);
            
            place.setAddress(address);
            
            place.setStreet(street);
            place.setCity(city);
            place.setRegion(region);
            place.setCountry(country);
            
            place.setZip(zip);
            
            place.setLat(lat);
            place.setLng(lng);
            
            place.setWikiURL(wikiURL);
            place.setFoursqVenueID(foursqVenueID);
            
            place.setPrimaryPhotoID(primaryPhotoID);
            place.setPhotoIDs(StringUtils.isEmpty(photoIDs) ? null : Arrays.asList(photoIDs.split("\\s*,\\s*")));
            
            place.setCityIDs(StringUtils.isEmpty(cityIDs) ? null : Arrays.asList(cityIDs.split("\\s*,\\s*")));            
            place.setDistrictIDs(StringUtils.isEmpty(districtIDs) ? null : Arrays.asList(districtIDs.split("\\s*,\\s*")));
            place.setBuildingIDs(StringUtils.isEmpty(buildingIDs) ? null : Arrays.asList(buildingIDs.split("\\s*,\\s*")));
            place.setVillageIDs(StringUtils.isEmpty(villageIDs) ? null : Arrays.asList(villageIDs.split("\\s*,\\s*")));
            
            ServiceResponse<String> response = placeService.create(place);
            map.put("place", response.getResponse());
            mav.setView(new RedirectView("place.htm?a="+PlaceAction.READ+"&id="+response.getResponse()));   
        }
        else {
            //CX: get amenity choices
            
            //CX: get place choices
            ServiceResponse<List<Place>> response1 = placeService.readAllByType(KPlaceTypes.CITY.getId(), 0, 0);
            ServiceResponse<List<Place>> response2 = placeService.readAllByType(KPlaceTypes.DISTRICT.getId(), 0, 0);
            ServiceResponse<List<Place>> response3 = placeService.readAllByType(KPlaceTypes.BUILDING.getId(), 0, 0);
            ServiceResponse<List<Place>> response4 = placeService.readAllByType(KPlaceTypes.VILLAGE.getId(), 0, 0);
            
            map.put("cities", response1.getResponse());
            map.put("districts", response2.getResponse());
            map.put("buildings", response3.getResponse());
            map.put("villages", response4.getResponse()); 
            
            mav.setViewName("placeadd");
        }
    }
    
    private void update(ModelAndView mav, Map map, HttpServletRequest request) {
        if (!StringUtils.isEmpty(request.getParameter("s"))) {             
            String id = request.getParameter("id");    
            String placeTypeID = request.getParameter("placeTypeID");
            
            String title = request.getParameter("title");
            String description = request.getParameter("description");
            String shortDescription = request.getParameter("shortDescription");
            String notes = request.getParameter("notes");
            
            String address = request.getParameter("address");
            
            String street = request.getParameter("street");
            String barangay = request.getParameter("barangay");
            String country = request.getParameter("country");
            String region = request.getParameter("region");
            String city = request.getParameter("city");
            
            String zip = request.getParameter("zip");
            
            String lat = request.getParameter("lat");
            String lng = request.getParameter("lng");
            
            String wikiURL = request.getParameter("wikiURL");
            String foursqVenueID = request.getParameter("foursqVenueID");
            
            String primaryPhotoID = request.getParameter("primaryPhotoID");
            String photoIDs = request.getParameter("photoIDs");
                        
            String cityIDs = request.getParameter("cityIDs");
            String districtIDs = request.getParameter("districtIDs");
            String buildingIDs = request.getParameter("buildingIDs");
            String villageIDs = request.getParameter("villageIDs");
            
            ServiceResponse<Place> response1 = placeService.read(id);              
            Place place = response1.getResponse();          

            if (place != null) {
                place.setPlaceTypeID(placeTypeID);
            
                place.setTitle(title);
                place.setDescription(description);
                place.setShortDescription(shortDescription);
                place.setNotes(notes);

                place.setAddress(address);
                
                place.setStreet(street);
                place.setCity(city);
                place.setRegion(region);
                place.setCountry(country);

                place.setZip(zip);
            
                place.setLat(lat);
                place.setLng(lng);

                place.setWikiURL(wikiURL);
                place.setFoursqVenueID(foursqVenueID);
                
                place.setPrimaryPhotoID(primaryPhotoID);
                place.setPhotoIDs(StringUtils.isEmpty(photoIDs) ? null : Arrays.asList(photoIDs.split("\\s*,\\s*")));
                                
                place.setCityIDs(StringUtils.isEmpty(cityIDs) ? null : Arrays.asList(cityIDs.split("\\s*,\\s*")));            
                place.setDistrictIDs(StringUtils.isEmpty(districtIDs) ? null : Arrays.asList(districtIDs.split("\\s*,\\s*")));
                place.setBuildingIDs(StringUtils.isEmpty(buildingIDs) ? null : Arrays.asList(buildingIDs.split("\\s*,\\s*")));
                place.setVillageIDs(StringUtils.isEmpty(villageIDs) ? null : Arrays.asList(villageIDs.split("\\s*,\\s*")));

                ServiceResponse<Boolean> response = placeService.update(place);
                map.put("place", response.getResponse());
                mav.setView(new RedirectView("place.htm?a="+PlaceAction.READ+"&id="+id));
            }
            else {
                mav.setView(new RedirectView("place.htm"));                
            }
        }        
        else {                       
            String id = request.getParameter("id");    
            ServiceResponse<Place> response = placeService.read(id);  
            
            ServiceResponse<List<Place>> response1 = placeService.readAllByType(KPlaceTypes.CITY.getId(), 0, 0);
            ServiceResponse<List<Place>> response2 = placeService.readAllByType(KPlaceTypes.DISTRICT.getId(), 0, 0);
            ServiceResponse<List<Place>> response3 = placeService.readAllByType(KPlaceTypes.BUILDING.getId(), 0, 0);
            ServiceResponse<List<Place>> response4 = placeService.readAllByType(KPlaceTypes.VILLAGE.getId(), 0, 0);
            
            map.put("place", response.getResponse());  
            
            map.put("cities", response1.getResponse());
            map.put("districts", response2.getResponse());
            map.put("buildings", response3.getResponse());
            map.put("villages", response4.getResponse());  
            
            mav.setViewName("placeedit");
        }
    }
    
    private void delete(ModelAndView mav, Map map, HttpServletRequest request) {        
        String id = request.getParameter("id");
        ServiceResponse<Boolean> response = placeService.delete(id);        
        mav.setView(new RedirectView("place.htm?a="+PlaceAction.READ_ALL));
    }
       
    private void createPhoto(ModelAndView mav, Map map, HttpServletRequest request, Map parameterMap) {        
        Map<String, String> formfields = (Map<String, String>) parameterMap.get("formfields");
        List<Photo> photos = new ArrayList<Photo>();
        
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);       
        String placeID = formfields.get("id"); 
        
        try {
            if (isMultipart) {
                List filefields = (List) parameterMap.get("filefields");
                Iterator iterator = filefields.iterator();

                while (iterator.hasNext()) {
                    FileItem item = (FileItem) iterator.next();

                    if (!item.isFormField()) {
                        String fileName = item.getName();
                        
                        if (!StringUtils.isEmpty(fileName)) {
                            String ext = "";
                            
                            if (StringUtils.containsIgnoreCase(fileName, ".jpg")) {
                                ext = ".jpg";
                            }
                            if (StringUtils.containsIgnoreCase(fileName, ".png")) {
                                ext = ".png";
                            }
                            
                            String genFileName = UUID.randomUUID().toString();                        
                            fileName = genFileName;
                            fileName = fileName + ext;
                            
                            String root = getServletContext().getRealPath("/");
                            root = SystemProperties.PHOTO_DIRECTORY;
                            File path = new File(root);

                            if (!path.exists()) {
                                boolean status = path.mkdirs();
                            }
                            File uploadedFile = new File(path + "/" + fileName );
                                                        
                            if (!uploadedFile.exists()) {
                                //CX: write photo
                                item.write(uploadedFile);
                                //CX: write standard and preview sizes
                                ImageProcessor proc = new ImageProcessor();
                                proc.createStandardSize(uploadedFile);
                                proc.createPreviewSize(uploadedFile);
                            }
                            photos.add(new Photo(root, fileName));
                        }
                    }
                }
            }

            if (formfields != null && !StringUtils.isEmpty((String) formfields.get("s"))) {                
                if (photos != null && photos.size() > 0) {
                    for (Photo photo : photos) {
                        photoService.createPlacePhoto(placeID, photo);
                        //ServiceResponse<String> response1 = photoService.createListingPhoto(listingID, photo);                        
                    }                    
                }
            }            
        } 
        catch (Exception ex) {
            ex.printStackTrace();
        }        
        
        mav.setView(new RedirectView("place.htm?a="+PlaceAction.UPDATE_PHOTO+"&id="+placeID));
        
    }  
    
    private void updatePhoto(ModelAndView mav, Map map, HttpServletRequest request, Map parameterMap) {
        String id = request.getParameter("id");      
        ServiceResponse<Place> response1 = placeService.read(id); 
        
        map.put("place", response1.getResponse());
        mav.setViewName("placeeditphoto");
    }
    
    private void deletePhoto(ModelAndView mav, Map map, HttpServletRequest request, Map parameterMap) {
        String placeID = request.getParameter("placeID");
        String photoID = request.getParameter("photoID");
        ServiceResponse<Boolean> response = photoService.deletePlacePhoto(placeID, photoID);        
        
        mav.setView(new RedirectView("place.htm?a="+PlaceAction.UPDATE_PHOTO+"&id="+placeID));
    }
}
